/*
helferlein.com ( http://www.helferlein.com )
Michael Tobisch

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions 
of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
DEALINGS IN THE SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text;
using System.Xml;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Services.Localization;
using System.Web;
using System.Collections;
using helferlein.DNN.Modules.BabelFish.Business;
using DotNetNuke.Services.Exceptions;
using DotNetNuke.Services.Mail;

namespace helferlein.DNN.Modules.Form.Business
{
   public class FormSubmissionInfo : IHydratable
   {
#region Private Properties
      private int? _portalID;
      private int _moduleID;
      private int _formSubmissionID;
      private string _formSubmission;
      private DateTime _formSubmissionDate;
      private bool _formSubmissionApproved;
      private string _formSubmissionIPAddress;
      private string _formSubmissionLocale;
      private FormSubmissionController _formSubmissionController = null;
      private FormItemController _formItemController = null;
      private BabelFishController _babelFishController = null;
      private ModuleController _moduleController = null;

      protected FormSubmissionController FormSubmissionController
      {
         get
         {
            if (_formSubmissionController == null)
            {
               _formSubmissionController = new FormSubmissionController();
               _formSubmissionController.Initialize(this.PortalID, this.ModuleID);
            }
            return _formSubmissionController;
         }
      }

      protected FormItemController FormItemController
      {
         get
         {
            if (_formItemController == null)
               _formItemController = new FormItemController();
            return _formItemController;
         }
      }

      protected BabelFishController BabelFishController
      {
         get
         {
            if (_babelFishController == null)
               _babelFishController = new BabelFishController();
            return _babelFishController;
         }
      }

      protected ModuleController ModuleController
      {
         get
         {
            if (_moduleController == null)
               _moduleController = new ModuleController();
            return _moduleController;
         }
      }
#endregion

#region Public Properties
      /// <summary>
      /// Gets and sets the PortalID
      /// </summary>
      public int PortalID
      {
         get
         {
            if (!(_portalID.HasValue))
            {
               // _portalID = this.ModuleController.GetModule(this.ModuleID).PortalID;
               _portalID = this.ModuleController.GetModule(this.ModuleID, Null.NullInteger, true).PortalID;
            }
            return _portalID.Value;
         }
      }

      /// <summary>
      /// Gets and sets the ModuleID
      /// </summary>
      public int ModuleID
      {
         get { return _moduleID; }
         set { _moduleID = value; }
      }

      /// <summary>
      /// Gets and sets the FormSubmissionID
      /// </summary>
      public int FormSubmissionID
      {
         get { return _formSubmissionID; }
         set { _formSubmissionID = value; }
      }

      /// <summary>
      /// Gets and sets the FormSubmission
      /// </summary>
      public string FormSubmission
      {
         get { return _formSubmission; }
         set { _formSubmission = value; }
      }

      /// <summary>
      /// Gets and sets the Submission date
      /// </summary>
      public DateTime FormSubmissionDate
      {
         get { return _formSubmissionDate; }
         set { _formSubmissionDate = value; }
      }

      /// <summary>
      /// Gets and sets the Approval flag
      /// </summary>
      public bool FormSubmissionApproved
      {
         get { return _formSubmissionApproved; }
         set { _formSubmissionApproved = value; }
      }

      /// <summary>
      /// Gets and sets the IP Address
      /// </summary>
      public string FormSubmissionIPAddress
      {
         get { return _formSubmissionIPAddress; }
         set { _formSubmissionIPAddress = value; }
      }

      public string FormSubmissionLocale
      {
         get { return _formSubmissionLocale; }
         set { _formSubmissionLocale = value; }
      }

      public string GetValue(string label)
      {
         XmlTextReader reader = new XmlTextReader(new StringReader(this.FormSubmission));
         reader.WhitespaceHandling = WhitespaceHandling.None;

         string value = String.Empty;
         string key = String.Empty;

         while (reader.ReadToFollowing("formItem"))
         {
            if (reader.ReadToFollowing("formItemSelectedValue"))
               value = reader.ReadString();
            if (reader.ReadToFollowing("formItemLabel"))
               key = reader.ReadString();
            if (key == label)
               break;
            else
            {
               value = string.Empty;
               key = string.Empty;
            }
         }
         return value;
      }
      
      public string GroupItemValue
      {
         get
         {
            if (this.FormSubmissionController.Settings["GroupOutputBy"] != null)
            {
               int formItemID = Convert.ToInt32(Convert.ToString(this.FormSubmissionController.Settings["GroupOutputBy"]).Substring(10));
               string label = this.BabelFishController.GetString(this.PortalID, this.FormSubmissionController.PortalSettings.DefaultLanguage, "helferlein.Form.FormItem." + formItemID.ToString(), "FormItemLabel").StringText;
               return this.GetValue(label);
            }
            else
               return string.Empty;
         }
      }

      public string HeadlineValue
      {
         get
         {
            if (this.FormSubmissionController.Settings["RenderAsHeadline"] != null)
            {
               int formItemID = Convert.ToInt32(Convert.ToString(this.FormSubmissionController.Settings["RenderAsHeadline"]).Substring(10));
               string label = this.BabelFishController.GetString(this.PortalID, this.FormSubmissionController.PortalSettings.DefaultLanguage, "helferlein.Form.FormItem." + formItemID.ToString(), "FormItemLabel").StringText;
               return this.GetValue(label);
            }
            else
               return string.Empty;
         }
      }

      public string ItemToAddValue
      {
         get
         {
            if (this.FormSubmissionController.Settings["AddToDropDownList"] != null)
            {
               int formItemID = Convert.ToInt32(Convert.ToString(this.FormSubmissionController.Settings["AddToDropDownList"]).Substring(10));
               string label = this.BabelFishController.GetString(this.PortalID, this.FormSubmissionController.PortalSettings.DefaultLanguage, "helferlein.Form.FormItem." + formItemID.ToString(), "FormItemLabel").StringText;
               return this.GetValue(label);
            }
            else
               return string.Empty;
         }
      }

      public string RecipientAddressValue
      {
         get
         {
            List<FormItemInfo> submission = this.GetSubmissionFromXml();
            string recipient = String.Empty;
            foreach (FormItemInfo fii in submission)
            {
               if (fii.FormItemType == FormItemType.SendTo)
               {
                  recipient = fii.FormItemSelectedValue;
                  break;
               }
            }
            return recipient;
         }
      }

      public string ToText()
      {
         return this.ToText(false, false);
      }

      public string ToText(bool showHidden, bool includeIPAddressInEmail)
      {
         StringBuilder text = new StringBuilder("");
         try
         {
            List<FormItemInfo> formSubmission = GetSubmissionFromXml();
            foreach (FormItemInfo formItem in formSubmission)
            {
               if (((formItem.FormItemType == FormItemType.Hidden) && (showHidden)) || (formItem.FormItemType != FormItemType.Hidden))
                  text.Append(HttpContext.Current.Server.HtmlDecode(formItem.FormItemLabel) + ":\r\n" + new string('-', formItem.FormItemLabel.Length + 1) + "\r\n");
               switch (formItem.FormItemType)
               {
                  case FormItemType.MultipleSelect:
                     if (String.IsNullOrEmpty(formItem.FormItemSelectedValue))
                        text.Append("-\r\n");
                     else
                     {
                        string[] values = formItem.FormItemSelectedValue.Split(new char[] { ';' });
                        foreach (string value in values)
                        {
                           text.Append("- ");
                           if ((formItem.FormItemOther) && (value.StartsWith("OTHER_FOR_CONTROL_")))
                           {
                              if (String.IsNullOrEmpty(formItem.FormItemOtherValue))
                                 text.Append("-");
                              else
                                 text.Append(HttpContext.Current.Server.HtmlDecode(formItem.FormItemOtherValue));
                           }
                           else
                              text.Append(value);
                           text.Append("\r\n");
                        }
                     }
                     // <!-- To make user Lode_Leroy's "Other" feathure work with text-formatted mails as well...
                     if ((!(String.IsNullOrEmpty(formItem.FormItemSelectedValue))) && (!(String.IsNullOrEmpty(formItem.FormItemOtherValue))))
                     {
                        text.Append(Localization.GetString("Other.Text", "~/DesktopModules/helferlein_Form/App_LocalResources/SharedResources.ascx.resx"));
                        text.Append(": ");
                        text.Append(HttpContext.Current.Server.HtmlDecode(formItem.FormItemOtherValue));
                        text.Append("\r\n");
                     }
                     // To make user Lode_Leroy's "Other" feathure work with text-formatted mails as well... -->
                     break;
                  case FormItemType.Checkbox:
                     text.Append(((Convert.ToBoolean(formItem.FormItemSelectedValue)) ? Localization.GetString("Yes.Text") : Localization.GetString("No.Text")) + "\r\n");
                     break;
                  case FormItemType.Date:
                     if (String.IsNullOrEmpty(formItem.FormItemSelectedValue))
                        text.Append("-\r\n");
                     else
                     {
                        text.Append(DateTime.FromBinary(Convert.ToInt64(formItem.FormItemSelectedValue)).ToString("d"));
                        text.Append("\r\n");
                     }
                     break;
                  case FormItemType.FileUpload:
                     if (String.IsNullOrEmpty(formItem.FormItemSelectedValue))
                        text.Append("-");
                     else
                     {
                        if (HttpContext.Current != null)
                        {
                           text.Append(this.LinkToUploadedFile(formItem.FormItemSelectedValue));
                           if (!(String.IsNullOrEmpty(formItem.FormItemOriginalFileName)))
                           {
                              text.Append(" (");
                              text.Append(HttpContext.Current.Server.HtmlDecode(formItem.FormItemOriginalFileName));
                              text.Append(")");
                           }
                           text.Append("\r\n");
                        }
                        else
                           text.Append("\r\n");
                     }
                     break;
                  case FormItemType.Hidden:
                     if (String.IsNullOrEmpty(formItem.FormItemSelectedValue))
                        text.Append("-");
                     else
                     {
                        if (showHidden)
                        {
                           text.Append(HttpContext.Current.Server.HtmlDecode(formItem.FormItemSelectedValue));
                           text.Append("\r\n");
                        }
                     }
                     break;
                  // <!-- To make user Lode_Leroy's "Other" feathure work with text-formatted mails as well...
                  case FormItemType.RadioButtonList:
                  case FormItemType.DropDownList:
                     if (String.IsNullOrEmpty(formItem.FormItemSelectedValue))
                        text.Append("-");
                     else
                     {
                        if ((formItem.FormItemOther) && (formItem.FormItemSelectedValue.StartsWith("OTHER_FOR_CONTROL_")))
                           if (String.IsNullOrEmpty(formItem.FormItemOtherValue))
                              text.Append("-");
                           else
                              text.Append(HttpContext.Current.Server.HtmlDecode(formItem.FormItemOtherValue));
                        else
                           text.Append(HttpContext.Current.Server.HtmlDecode(formItem.FormItemSelectedValue));
                     }
                     text.Append("\r\n");
                     break;
                  // To make user Lode_Leroy's "Other" feathure work with text-formatted mails as well... -->
                  default:
                     if (String.IsNullOrEmpty(formItem.FormItemSelectedValue))
                        text.Append("-");
                     else
                     {
                        text.Append(HttpContext.Current.Server.HtmlDecode(formItem.FormItemSelectedValue));
                        text.Append("\r\n");
                     }
                     break;
               }
               text.Append("\r\n");
            }
            if (includeIPAddressInEmail)
            {
               text.Append(Localization.GetString("RemoteIPCaptionLabel.Text", "~/DesktopModules/helferlein_Form/App_LocalResources/SharedResources.resx"));
               text.Append(": ");
               text.Append(this.FormSubmissionIPAddress);
               text.Append("\r\n");
            }
         }
         catch(Exception ex)
         {
            Exceptions.LogException(ex);
            text.Remove(0, text.Length);
         }
         return text.ToString();
      }

      /// <summary>
      /// Gets a string representing the form submission in an HTML table
      /// </summary>

      public string ToHtml()
      {
         return this.ToHtml(false, false, Convert.ToBoolean(this.FormSubmissionController.Settings["ShowLabels"]), false, false);
      }

      public string ToHtml(bool showGroupItem, bool showHeaderItem, bool showLabels, bool showHidden)
      {
         return this.ToHtml(showGroupItem, showHeaderItem, showLabels, showHidden, false);
      }

      public string ToHtml(bool showGroupItem, bool showHeaderItem, bool showLabels, bool showHidden, bool includeIPAddressInEmail)
      {
         StringBuilder html = new StringBuilder("");
         try
         {
            html.Append("<table width=\"100%\" cellpadding=\"4\" cellspacing=\"0\" border=\"0\">");
            if (showLabels)
               html.Append("<colgroup><col width=\"20%\" align=\"right\" /><col width=\"80%\" /></colgroup>");

            StringBuilder htmlRow = new StringBuilder("");
            List<FormItemInfo> formSubmission = GetSubmissionFromXml();

            foreach (FormItemInfo formItem in formSubmission)
            {
               string groupItemLabel = String.Empty;
               if ((showGroupItem) && (!(String.IsNullOrEmpty(Convert.ToString(this.FormSubmissionController.Settings["GroupOutputBy"])))))
                  groupItemLabel = this.BabelFishController.GetString(this.PortalID, this.FormSubmissionController.PortalSettings.DefaultLanguage, "helferlein.Form.FormItem." + Convert.ToString(this.FormSubmissionController.Settings["GroupOutputBy"]).Substring(10), "FormItemLabel").StringText;
               string headlineItemLabel = String.Empty;
               if ((showHeaderItem) && (!(String.IsNullOrEmpty(Convert.ToString(this.FormSubmissionController.Settings["RenderAsHeadline"])))))
                  headlineItemLabel = this.BabelFishController.GetString(this.PortalID, this.FormSubmissionController.PortalSettings.DefaultLanguage, "helferlein.Form.FormItem." + Convert.ToString(this.FormSubmissionController.Settings["RenderAsHeadline"]).Substring(10), "FormItemLabel").StringText;

               if ( ((showGroupItem) || ((formItem.FormItemLabel != groupItemLabel) || (this.GroupItemValue == string.Empty))) && 
                     ((showHeaderItem) || ((formItem.FormItemLabel != headlineItemLabel) || (this.HeadlineValue == string.Empty))) &&
                     ((formItem.FormItemType != FormItemType.SendTo) || ((formItem.FormItemType == FormItemType.SendTo) && (Convert.ToBoolean(this.FormSubmissionController.Settings["ShowRecipient"])))))
               {
                  if (((formItem.FormItemType == FormItemType.Hidden) && (showHidden)) || (formItem.FormItemType != FormItemType.Hidden))
                  {
                     html.Append("<tr>");
                     if (showLabels)
                        html.Append("<td class=\"SubHead\" valign=\"top\">" + formItem.FormItemLabel + ":</td>");
                     html.Append("<td class=\"Normal\" valign=\"top\">");
                  }
                  switch (formItem.FormItemType)
                  {
                     case FormItemType.TextArea:
                        if (String.IsNullOrEmpty(formItem.FormItemSelectedValue))
                           html.Append("-");
                        else
                           if (HttpContext.Current == null)
                              html.Append(formItem.FormItemSelectedValue);
                           else
                              html.Append(HttpContext.Current.Server.HtmlDecode(formItem.FormItemSelectedValue));
                        break;
                     case FormItemType.MultipleSelect:
                        html.Append("<ul class=\"ListStyle\">");
                        if (String.IsNullOrEmpty(formItem.FormItemSelectedValue))
                           html.Append("<li>-</li>");
                        else
                        {
                           string[] values = formItem.FormItemSelectedValue.Split(new char[] { ';' });
                           foreach (string value in values)
                           {
                              html.Append("<li>");
                              if ((formItem.FormItemOther) && (value.StartsWith("OTHER_FOR_CONTROL_")))
                              {
                                 if (String.IsNullOrEmpty(formItem.FormItemOtherValue))
                                    html.Append("-");
                                 else
                                    html.Append(formItem.FormItemOtherValue);
                              }
                              else
                                 html.Append(value);
                              html.Append("</li>");
                           }
                        }
                        html.Append("</ul>");
                        break;
                     case FormItemType.Checkbox:
                     case FormItemType.SendCopy:
                        html.Append((Convert.ToBoolean(formItem.FormItemSelectedValue)) ? Localization.GetString("Yes.Text") : Localization.GetString("No.Text"));
                        break;
                     case FormItemType.EMailAddress:
                        if (String.IsNullOrEmpty(formItem.FormItemSelectedValue))
                           html.Append("-");
                        else
                        {
                           html.Append("<a href=\"mailto:");
                           html.Append(formItem.FormItemSelectedValue);
                           html.Append("\">");
                           html.Append(formItem.FormItemSelectedValue);
                           html.Append("</a>");
                        }
                        break;
                     case FormItemType.WebSite:
                        if (String.IsNullOrEmpty(formItem.FormItemSelectedValue))
                           html.Append("-");
                        else
                        {
                           string target;
                           try
                           {
                              switch (formItem.FormItemLinkTarget)
                              {
                                 case LinkTarget.Blank:
                                    target = " target=\"_blank\"";
                                    break;
                                 case LinkTarget.Parent:
                                    target = " target=\"_parent\"";
                                    break;
                                 case LinkTarget.Self:
                                    target = " target=\"_self\"";
                                    break;
                                 case LinkTarget.Top:
                                    target = " target=\"_top\"";
                                    break;
                                 default:
                                    target = string.Empty;
                                    break;
                              }
                           }
                           catch (Exception ex)
                           {
                              Exceptions.LogException(ex);
                              target = String.Empty;
                           }
                           html.Append("<a href=\"");
                           html.Append(formItem.FormItemSelectedValue);
                           html.Append("\"");
                           html.Append(target);
                           html.Append(">");
                           html.Append(formItem.FormItemSelectedValue);
                           html.Append("</a>");
                        }
                        break;
                     case FormItemType.Date:
                        if (String.IsNullOrEmpty(formItem.FormItemSelectedValue))
                           html.Append("-");
                        else
                           html.Append(DateTime.FromBinary(Convert.ToInt64(formItem.FormItemSelectedValue)).ToString("d"));
                        break;
                     case FormItemType.SendTo:
                        if (String.IsNullOrEmpty(formItem.FormItemSelectedValue))
                           html.Append("-");
                        else
                        {
                           if (Convert.ToBoolean(this.FormSubmissionController.Settings["ShowRecipient"]))
                           {
                              html.Append("<a href=\"mailto:");
                              html.Append((formItem.FormItemSelectedValue.Substring(formItem.FormItemSelectedValue.IndexOf('[') + 1, formItem.FormItemSelectedValue.IndexOf(']') - formItem.FormItemSelectedValue.IndexOf('[') - 1)).Trim());
                              html.Append("\">");
                              html.Append((formItem.FormItemSelectedValue.Substring(0, formItem.FormItemSelectedValue.IndexOf('[') - 1)).Trim());
                              html.Append("</a>");
                           }
                        }
                        break;
                     case FormItemType.FileUpload:
                        if ((HttpContext.Current == null) || String.IsNullOrEmpty(formItem.FormItemSelectedValue))
                           html.Append("-");
                        else
                        {
                           html.Append("<a href=\"");
                           html.Append(this.LinkToUploadedFile(formItem.FormItemSelectedValue));
                           html.Append("\" target=\"_blank\">");
                           if (String.IsNullOrEmpty(formItem.FormItemOriginalFileName))
                              html.Append(formItem.FormItemSelectedValue);
                           else
                              html.Append(formItem.FormItemOriginalFileName);
                           html.Append("</a>");
                        }
                        break;
                     case FormItemType.Hidden:
                        if ((!(showHidden)) || String.IsNullOrEmpty(formItem.FormItemSelectedValue))
                           html.Append("-");
                        else
                           html.Append(String.IsNullOrEmpty(formItem.FormItemSelectedValue) ? "-" : formItem.FormItemSelectedValue);
                        break;
                     case FormItemType.RadioButtonList:
                     case FormItemType.DropDownList:
                        if (String.IsNullOrEmpty(formItem.FormItemSelectedValue))
                           html.Append("-");
                        else
                           if ((formItem.FormItemOther) && (formItem.FormItemSelectedValue.StartsWith("OTHER_FOR_CONTROL_")))
                           {
                              if (String.IsNullOrEmpty(formItem.FormItemOtherValue))
                                 html.Append("-");
                              else
                                 html.Append(formItem.FormItemOtherValue);
                           }
                           else
                              html.Append(formItem.FormItemSelectedValue);
                        break;
                     default:
                        if (String.IsNullOrEmpty(formItem.FormItemSelectedValue))
                           html.Append("-");
                        else
                           html.Append(formItem.FormItemSelectedValue);
                        break;
                  }
                  if (((formItem.FormItemType == FormItemType.Hidden) && (showHidden)) || (formItem.FormItemType != FormItemType.Hidden))
                     html.Append("</td></tr>");
               }
            }
            if (includeIPAddressInEmail)
            {
               html.Append("<tr><td class=\"SubHead\" valign=\"top\">");
               html.Append(Localization.GetString("RemoteIPCaptionLabel.Text", "~/DesktopModules/helferlein_Form/App_LocalResources/SharedResources.resx"));
               html.Append(":</td><td>");
               html.Append(this.FormSubmissionIPAddress);
               html.Append("</td></tr>");
            }
            html.Append("</table>");
         }
         catch(Exception ex)
         {
            Exceptions.LogException(ex);
            html.Remove(0, html.Length);
         }
         return html.ToString();
      }

      public string GetBasicForm()
      {
         List<FormItemInfo> theForm = this.GetSubmissionFromXml();
         theForm.Sort(new FormItemComparer().Compare);
         StringBuilder basicForm = new StringBuilder();
         basicForm.Append("<Form>");

         foreach (FormItemInfo fii in theForm)
         {
            basicForm.Append("<FormItem>");
            basicForm.Append(String.Format("<FormItemType>{0}</FormItemType>", fii.FormItemType));
            basicForm.Append(String.Format("<SortValue>{0}</SortValue>", fii.SortValue));
            basicForm.Append(String.Format("<FormItemLabel>{0}</FormItemLabel>", fii.FormItemLabel));
            basicForm.Append("</FormItem>");
         }
         basicForm.Append("</Form>");
         return basicForm.ToString();
      }

      public List<FormItemInfo> GetSubmissionFromXml()
      {
         return this.GetSubmissionFromXml(this.FormSubmission);
      }

      /// <summary>
      /// Returns a Submission object from a submission stored as an XML string
      /// </summary>
      /// <param name="xmlSubmissions"></param>
      /// <returns></returns>
      public List<FormItemInfo> GetSubmissionFromXml(string xmlSubmissions)
      {
         XmlTextReader xmlReader = new XmlTextReader(new StringReader(this.FormSubmission));
         xmlReader.WhitespaceHandling = WhitespaceHandling.None;

         List<FormItemInfo> formSubmission = new List<FormItemInfo>();

         while (xmlReader.Read())
         {
            if ((xmlReader.NodeType == XmlNodeType.Element) && (xmlReader.Name == "formItem"))
            {
               XmlReader xmlSubTree = xmlReader.ReadSubtree();
               formSubmission.Add(GetItemFromXml(xmlSubTree));
               xmlSubTree.Close();
            }
         }
         xmlReader.Close();
         return formSubmission;
      }

      /// <summary>
      /// Reurns a form item from an XML Submission
      /// </summary>
      /// <param name="xmlReader"></param>
      /// <returns></returns>
      public FormItemInfo GetItemFromXml(XmlReader xmlReader)
      {
         FormItemInfo formItem = new FormItemInfo();

         while (xmlReader.Read())
         {
            if (xmlReader.NodeType == XmlNodeType.Element)
            {
               switch (xmlReader.Name)
               {
                  case "formItemType":
                     formItem.FormItemType = (FormItemType)Enum.GetValues(typeof(FormItemType)).GetValue(Convert.ToInt32(xmlReader.ReadString()) - 1);
                     break;
                  case "formItemValue":
                     formItem.FormItemValue = xmlReader.ReadString();
                     break;
                  case "formItemSelectedValue":
                     formItem.FormItemSelectedValue = xmlReader.ReadString();
                     break;
                  case "formItemOriginalFileName":
                     formItem.FormItemOriginalFileName = xmlReader.ReadString();
                     break;
                  case "formItemLabel":
                     formItem.FormItemLabel = xmlReader.ReadString();
                     break;
                  case "formItemRepeatColumns":
                     if (!(xmlReader.IsEmptyElement))
                     {
                        string value = xmlReader.ReadString();
                        int formItemRepeatColumns = 0;
                        if (Int32.TryParse(value, out formItemRepeatColumns))
                           formItem.FormItemRepeatColumns = formItemRepeatColumns;
                     }
                     break;
                  case "formItemSortValue":
                     formItem.SortValue = Convert.ToInt32(xmlReader.ReadString());
                     break;
                  case "formItemRequired":
                     formItem.FormItemRequired = Convert.ToBoolean(xmlReader.ReadString());
                     break;
                  case "formItemWidth":
                     if (!(xmlReader.IsEmptyElement))
                     {
                        string value = xmlReader.ReadString();
                        int formItemWidth = 0;
                        if (Int32.TryParse(value, out formItemWidth))
                           formItem.Width = formItemWidth;
                     }
                     break;
                  case "formItemHeight":
                     if (!(xmlReader.IsEmptyElement))
                     {
                        string value = xmlReader.ReadString();
                        int formItemHeight = 0;
                        if (Int32.TryParse(value, out formItemHeight))
                           formItem.Height = formItemHeight;
                     }
                     break;
                  case "formItemLinkTarget":
                     if (!(xmlReader.IsEmptyElement))
                     {
                        try
                        {
                           formItem.FormItemLinkTarget = (LinkTarget)Enum.GetValues(typeof(LinkTarget)).GetValue(Convert.ToInt32(xmlReader.ReadString()) - 1);
                        }
                        catch
                        {
                           formItem.FormItemLinkTarget = LinkTarget.None;
                        }
                     }
                     else
                        formItem.FormItemLinkTarget = LinkTarget.None;
                     break;
                  case "formItemValidationExpression":
                     if (!(xmlReader.IsEmptyElement))
                        formItem.ValidationExpression = xmlReader.ReadString();
                     break;
                  case "formItemOther":
                     formItem.FormItemOther = Convert.ToBoolean(xmlReader.ReadString());
                     break;
                  case "formItemOtherValue":
                     if (!(xmlReader.IsEmptyElement))
                        formItem.FormItemOtherValue = xmlReader.ReadString();
                     break;
                  case "formItemHelpText":
                     if (!(xmlReader.IsEmptyElement))
                        formItem.FormItemHelpText = xmlReader.ReadString();
                     break;
                  case "formItemTemplate":
                     if (!(xmlReader.IsEmptyElement))
                        formItem.FormItemTemplate = xmlReader.ReadString();
                     break;
                  default:
                     break;
               }
            }
         }
         return formItem;
      }
#endregion

#region Constructors
      public FormSubmissionInfo()
      {
      }

      public FormSubmissionInfo(int portalID, int moduleID, int formSubmissionID, string formSubmission,
         DateTime formSubmissionDate, bool formSubmissionApproved, string formSubmissionIPAddress, string formSubmissionLocale)
      {
         this.ModuleID = moduleID;
         this.FormSubmissionID = formSubmissionID;
         this.FormSubmission = formSubmission;
         this.FormSubmissionDate = formSubmissionDate;
         this.FormSubmissionApproved = formSubmissionApproved;
         this.FormSubmissionIPAddress = formSubmissionIPAddress;
         this.FormSubmissionLocale = formSubmissionLocale;
      }
#endregion

#region Private Methods
      private string LinkToUploadedFile(string fileName)
      {
         StringBuilder linkToUploadedFile = new StringBuilder();
         linkToUploadedFile.Append(HttpContext.Current.Request.ServerVariables["HTTPS"] == "off" ? "http://" : "https://");
         linkToUploadedFile.Append(HttpContext.Current.Request.ServerVariables["SERVER_NAME"]);
         linkToUploadedFile.Append(HttpContext.Current.Request.ApplicationPath);
         linkToUploadedFile.Append(linkToUploadedFile[linkToUploadedFile.Length - 1] == '/' ? String.Empty : "/");
         linkToUploadedFile.Append(this.FormSubmissionController.PortalInfo.HomeDirectory);
         linkToUploadedFile.Append(linkToUploadedFile[linkToUploadedFile.Length - 1] == '/' ? String.Empty : "/");
         linkToUploadedFile.Append("helferlein/helferlein_Form/");
         linkToUploadedFile.Append(Base.UPLOAD_FOLDER);
         linkToUploadedFile.Append("/");
         linkToUploadedFile.Append(this.ModuleID);
         linkToUploadedFile.Append("/");
         linkToUploadedFile.Append(fileName);
         return linkToUploadedFile.ToString();
      }
#endregion

#region IHydratable Member
      public void Fill(IDataReader dr)
      {
         this.ModuleID = Convert.ToInt32(Null.SetNull(dr["ModuleID"], this.ModuleID));
         this.FormSubmissionID = Convert.ToInt32(Null.SetNull(dr["FormSubmissionID"], this.FormSubmissionID));
         this.FormSubmission = Convert.ToString(Null.SetNull(dr["FormSubmission"], this.FormSubmission));
         this.FormSubmissionDate = Convert.ToDateTime(Null.SetNull(dr["FormSubmissionDate"], this.FormSubmissionDate));
         this.FormSubmissionApproved = Convert.ToBoolean(Null.SetNull(dr["FormSubmissionApproved"], this.FormSubmissionApproved));
         this.FormSubmissionIPAddress = Convert.ToString(Null.SetNull(dr["FormSubmissionIPAddress"], this.FormSubmissionIPAddress));
         this.FormSubmissionLocale = Convert.ToString(Null.SetNull(dr["FormSubmissionLocale"], this.FormSubmissionLocale));
         this._portalID = Convert.ToInt32(Null.SetNull(dr["PortalID"], this.PortalID));
      }

      public int KeyID
      {
         get { return this.FormSubmissionID; }
         set { this.FormSubmissionID = value; }
      }
#endregion
   }

#region SubmissionComparer class
   public class SubmissionComparer : IComparer<FormSubmissionInfo>
   {
      private string _sortExpression;
      public String SortExpression
      {
         get { return _sortExpression; }
         set { _sortExpression = value; }
      }

      public SubmissionComparer(string sortExpression)
      {
         this.SortExpression = sortExpression;
      }

      public int Compare(FormSubmissionInfo x, FormSubmissionInfo y)
      {
         if (x.GetValue(this.SortExpression) == y.GetValue(this.SortExpression))
            return y.FormSubmissionDate.CompareTo(x.FormSubmissionDate);
         else
            return x.GetValue(this.SortExpression).CompareTo(y.GetValue(this.SortExpression));
      }
   }
#endregion
}